commit - 696d8188d3a1f41988285e7d3f1df6505c59c017
commit + e774592a186abac652c858f5fff5c6228bc1ffd8
blob - e61803b676a8709506ac851a1cac86c1a8d911c8
blob + d15dff7b5ff689dc2644879736a52743c47b151b
--- README.md
+++ README.md
) -}}
```
+### slideshow
+
+Отображает слайдшоу, создавая простую HTML-структуру:
+
+```html
+<div class="slideshow">
+ <img class="slideshow-slide">
+ <img class="slideshow-slide">
+</div>
+```
+
+Каждое изображение отображается через partial `image`, поэтому изображения, которые Hugo умеет обрабатывать, получают адаптивные варианты.
+
+`images` может быть одиночной строкой — слайдшоу из одного изображения — или списком. Элемент списка может быть:
+
+* строкой — путём к ресурсу страницы, глобальному ресурсу, путём от корня сайта или абсолютным URL;
+* Hugo image resource;
+* `dict` с ключами `image` (ресурс или путь), `src`, `alt`, `title` и `attributes` (атрибуты `<img>`).
+
+Относительный путь сначала ищется в ресурсах страницы, затем в глобальных ресурсах. Если разрешить его не удалось, сборка завершается ошибкой. Пути от корня сайта и абсолютные URL передаются в `src` без изменений.
+
+Атрибуты контейнера передаются через `attributes`; переданный `class` дополняет, а не заменяет класс `slideshow`. Для изображений дополнительно устанавливается класс `slideshow-slide`.
+
+Всем слайдам устанавливается `decoding="async"`, слайдам после первого — `loading="lazy"`: скрытые слайды не загружаются заранее. Значения переопределяются через `attributes` изображения.
+
+Контейнеру устанавливается CSS-переменная `--slide-count`, каждому слайду — `--slide-index` (с нуля). Они позволяют сайту строить анимацию перелистывания без знания разметки, например:
+
+```css
+.slideshow-slide {
+ animation-delay: calc(var(--slide-index) * 4s);
+ animation-duration: calc(var(--slide-count) * 4s);
+}
+```
+
+Переданный в `attributes` `style` сохраняется; переменные дописываются к нему.
+
+Параметры `widths`, `sizes` и `mode` передаются каждому изображению; без них используются настройки `radium.images`.
+
+Например:
+
+```go-html-template
+{{- partial "slideshow.html" (dict
+ "page" .
+ "images" (slice
+ "photo-1.jpg"
+ (dict "src" "photo-2.jpg" "alt" "Описание")
+ )
+ "attributes" (dict "class" "hero")
+) -}}
+```
+
### publish/security-txt
Генерирует ресурс `.well-known/security.txt` по RFC 9116.
Поддерживает обычную и Markdown-нотацию shortcode.
+### slideshow
+
+Создаёт слайдшоу через одноимённый partial.
+
+Изображения передаются внутренним содержимым — по одному пути или URL в строке:
+
+```md
+{{< slideshow >}}
+photo-1.jpg
+photo-2.jpg
+{{< /slideshow >}}
+```
+
+или параметром `images` через запятую:
+
+```md
+{{< slideshow images="photo-1.jpg, photo-2.jpg" />}}
+```
+
+Относительные пути разрешаются в ресурсах страницы и глобальных ресурсах; неразрешимый относительный путь завершает сборку ошибкой. Пути от корня сайта и абсолютные URL используются как есть.
+
+Поддерживаются атрибуты контейнера:
+
+* `class`;
+* `id`;
+* `role`;
+* `tabindex`;
+* `aria-label`;
+* `aria-hidden`.
+
+Также можно передать параметры `widths`, `sizes` и `mode`, управляющие генерацией адаптивных вариантов (см. partial `image`).
+
+Для `alt`, `title` и других атрибутов отдельных изображений используйте partial `slideshow` напрямую.
+
### video
Создаёт элемент `<video>`.
blob - /dev/null
blob + 1600c96b4db6dbbcddf90550dc247d0bc913e9df (mode 644)
--- /dev/null
+++ layouts/_partials/slideshow.html
+{{- $page := .page -}}
+{{- $images := .images | default slice -}}
+{{- $attributes := .attributes | default dict -}}
+
+
+{{/* Container class */}}
+
+{{- $class := "slideshow" -}}
+
+{{- with $attributes.class -}}
+ {{- $class = printf "slideshow %s" . -}}
+{{- end -}}
+
+{{- $attributes = merge $attributes (dict "class" $class) -}}
+
+
+{{/*
+ Expose slide count as a CSS custom property so that site CSS
+ can derive animation timing without knowing the markup.
+
+ Caller style is preserved.
+*/}}
+
+{{- $style := printf "--slide-count: %d" (len $images) -}}
+
+{{- with $attributes.style -}}
+ {{- $style = printf "%s; %s" . $style -}}
+{{- end -}}
+
+{{- $attributes = merge $attributes (dict "style" $style) -}}
+
+
+{{/* A single string is accepted as a one-item slideshow */}}
+
+{{- if eq (printf "%T" $images) "string" -}}
+ {{- $images = slice $images -}}
+{{- end -}}
+
+{{- if not (reflect.IsSlice $images) -}}
+ {{- errorf "slideshow.html: images must be a slice or a string" -}}
+{{- end -}}
+
+{{- if not $images -}}
+ {{- errorf "slideshow.html: images is required" -}}
+{{- end -}}
+
+
+<div{{ partial "attrs.html" $attributes | safeHTMLAttr }}>
+ {{- range $index, $item := $images -}}
+
+
+ {{/*
+ Normalize the item.
+
+ An item can be:
+ - a string: path or URL;
+ - an image resource;
+ - a dict: image, src, alt, title, attributes.
+ */}}
+
+ {{- $image := false -}}
+ {{- $src := "" -}}
+ {{- $imageAttributes := dict -}}
+
+ {{- if reflect.IsMap $item -}}
+
+ {{- $image = $item.image | default false -}}
+
+ {{- if eq (printf "%T" $image) "string" -}}
+ {{- $src = $image -}}
+ {{- $image = false -}}
+ {{- end -}}
+
+ {{- if not $src -}}
+ {{- $src = $item.src | default "" -}}
+ {{- end -}}
+
+ {{- $imageAttributes = $item.attributes | default dict -}}
+
+ {{- if isset $item "alt" -}}
+ {{- $imageAttributes = merge
+ $imageAttributes
+ (dict "alt" $item.alt)
+ -}}
+ {{- end -}}
+
+ {{- if isset $item "title" -}}
+ {{- $imageAttributes = merge
+ $imageAttributes
+ (dict "title" $item.title)
+ -}}
+ {{- end -}}
+
+ {{- else if reflect.IsImageResource $item -}}
+
+ {{- $image = $item -}}
+
+ {{- else if eq (printf "%T" $item) "string" -}}
+
+ {{- $src = $item -}}
+
+ {{- else -}}
+
+ {{- errorf "slideshow.html: unsupported image item %v" $item -}}
+
+ {{- end -}}
+
+
+ {{/*
+ Resolve a relative path against page resources, then global
+ resources. Root-relative paths and absolute URLs are passed
+ through as a plain src.
+ */}}
+
+ {{- if $src -}}
+
+ {{- $url := urls.Parse $src -}}
+
+ {{- if and
+ (not $url.IsAbs)
+ (not $url.Host)
+ (not (strings.HasPrefix $url.Path "/"))
+ -}}
+ {{- $path := strings.TrimPrefix "./" $url.Path -}}
+ {{- $resource := false -}}
+
+ {{- with $page -}}
+ {{- $resource = .Resources.Get $path -}}
+ {{- end -}}
+
+ {{- if not $resource -}}
+ {{- $resource = resources.Get $path -}}
+ {{- end -}}
+
+ {{- if $resource -}}
+ {{- $image = $resource -}}
+ {{- $src = "" -}}
+ {{- else -}}
+ {{- errorf
+ "slideshow.html: image %q not found in page or global resources"
+ $src
+ -}}
+ {{- end -}}
+
+ {{- end -}}
+
+ {{- end -}}
+
+
+ {{/*
+ Hidden slides are lazy-loaded; the first slide stays eager.
+ Caller attributes take precedence.
+ */}}
+
+ {{- $slideDefaults := dict "decoding" "async" -}}
+
+ {{- if gt $index 0 -}}
+ {{- $slideDefaults = merge $slideDefaults (dict "loading" "lazy") -}}
+ {{- end -}}
+
+ {{- $imageAttributes = merge $slideDefaults $imageAttributes -}}
+
+
+ {{/* Slide class */}}
+
+ {{- $class := "slideshow-slide" -}}
+
+ {{- with $imageAttributes.class -}}
+ {{- $class = printf "slideshow-slide %s" . -}}
+ {{- end -}}
+
+ {{- $imageAttributes = merge
+ $imageAttributes
+ (dict "class" $class)
+ -}}
+
+
+{{/*
+ Expose slide position as a CSS custom property; see
+ --slide-count above. Caller style is preserved.
+*/}}
+
+{{- $style := printf "--slide-index: %d" $index -}}
+
+{{- with $imageAttributes.style -}}
+ {{- $style = printf "%s; %s" . $style -}}
+ {{- end -}}
+
+{{- $imageAttributes = merge
+ $imageAttributes
+ (dict "style" $style)
+ -}}
+
+
+ {{- partial "image.html" (dict
+ "image" $image
+ "src" $src
+ "page" $page
+ "attributes" $imageAttributes
+ "widths" $.widths
+ "sizes" $.sizes
+ "mode" $.mode
+ ) -}}
+ {{- end -}}
+</div>
blob - /dev/null
blob + be62dee89fa41946a058bfcd37c26840215dc14c (mode 644)
--- /dev/null
+++ layouts/_shortcodes/slideshow.html
+{{- $allowed := slice
+ "class"
+ "id"
+ "role"
+ "tabindex"
+ "aria-label"
+ "aria-hidden"
+-}}
+
+{{- $attributes := partial "pick.html" (dict
+ "dict" .Params
+ "allowed" $allowed
+) -}}
+
+
+{{/*
+ Collect images from the images parameter (comma-separated)
+ and/or inner content (one path or URL per line).
+*/}}
+
+{{- $images := slice -}}
+
+{{- with .Get "images" -}}
+ {{- range (split . ",") -}}
+ {{- with . | strings.TrimSpace -}}
+ {{- $images = $images | append . -}}
+ {{- end -}}
+ {{- end -}}
+{{- end -}}
+
+{{- with .Inner -}}
+ {{- range (split . "\n") -}}
+ {{- with . | strings.TrimSpace -}}
+ {{- $images = $images | append . -}}
+ {{- end -}}
+ {{- end -}}
+{{- end -}}
+
+
+{{/* Width ladder: comma-separated string -> slice of ints */}}
+
+{{- $widths := .Get "widths" -}}
+
+{{- with $widths -}}
+ {{- $parsed := slice -}}
+ {{- range (split . ",") -}}
+ {{- with . | strings.TrimSpace -}}
+ {{- $parsed = $parsed | append (int .) -}}
+ {{- end -}}
+ {{- end -}}
+ {{- $widths = $parsed -}}
+{{- end -}}
+
+
+{{- if not $images -}}
+ {{- errorf "The %q shortcode requires at least one image, via the images parameter or inner content. See %s" .Name .Position -}}
+{{- end -}}
+
+{{- partial "slideshow.html" (dict
+ "page" .Page
+ "images" $images
+ "attributes" $attributes
+ "widths" $widths
+ "sizes" (.Get "sizes")
+ "mode" (.Get "mode")
+) -}}